<template>
  <view class="ltric">
    <view class="ltric_container" :style="lyricStyle">
      <text class="text" :class="index === activeIndex ? 'active' : ''" v-for="(item,index) in lyricData"
        :key="index">{{ item.words +'\n' }}</text>
    </view>
  </view>
</template>

<script setup>
  import innerAudioContext from '@/util/innerAudioContext.js'
  import {
    getMusicLyricAPI
  } from '@/common/api/musicAPI.js'
  import {
    ref,
    onMounted,
    watch,
    getCurrentInstance
  } from 'vue'

  const currentInstance = getCurrentInstance();
  const props = defineProps(['sid'])
  watch(() => props.sid, (newValue) => {
    getMusicLyric(props.sid)
  })
  // -- 格式化后的歌词
  const lyricData = ref([])
  const parseLrc = (lrc) => {
    lyricData.value = []
    let lines = lrc.split('\n')
    lines.forEach((item, index) => {
      if (item) {
        const parts = item.split(']')
        const timeStr = parts[0].substring(1)
        let str = ''
        if(parts.length <= 1){
          str = item
        }
        const obj = {
          time: parseTime(timeStr) || 0,
          words: parts[1] || str
        }
        lyricData.value.push(obj)
      }
    })
  }
  // 解析时间字符串
  const parseTime = (timeStr) => {
    let parts = timeStr.split(':')
    return +parts[0] * 60 + +parts[1]
  }
  // 获取歌词
  const getMusicLyric = async (id) => {
    const res = await getMusicLyricAPI(id)
    if (res.code !== 200) return uni.showToast({
      title: '获取歌词失败！',
      duration: 2000,
      icon: 'error'
    })
    parseLrc(res.lrc.lyric)
  }
  onMounted(async () => {
    await getMusicLyric(props.sid)
    const ltric = uni.createSelectorQuery().in(currentInstance).select('.ltric')
    ltric.fields({
      size: true,
      scrollOffset: true,
      dataset: true
    }, data => {
      clientHeight.value = data.height
    }).exec();
    const text = uni.createSelectorQuery().in(currentInstance).select('.text')
    text.boundingClientRect(data => {
      textHeight.value = data.height
    }).exec();
    const ltric_container = uni.createSelectorQuery().in(currentInstance).select('.ltric_container')
    ltric_container.boundingClientRect(data => {
      ltricHeight.value = data.height - clientHeight.value
    }).exec()
  })
  // 容器高度
  const clientHeight = ref(0)
  // 单行歌词高度
  const textHeight = ref(0)
  // 歌词最大高度
  const ltricHeight = ref(0)
  // 正在播放歌词下标
  const activeIndex = ref(-1)
  // 歌词播放样式
  const lyricStyle = ref({})
  // 监听音频更新事件
  innerAudioContext.onTimeUpdate(() => {
    activeIndex.value = findIndex()
    let offset = textHeight.value * activeIndex.value + textHeight.value / 2 - clientHeight.value / 2
    if (offset < 0) {
      offset = 0
    }
    if (offset > ltricHeight.value) {
      offset = ltricHeight.value
    }
    lyricStyle.value = {
      transform: `translateY(-${offset}px)`
    }
  })
  // 计算出lyricData数组中，因该高亮显示的歌词下标
  const findIndex = () => {
    const currentTime = innerAudioContext.currentTime()
    for (let i = 0; i < lyricData.value.length; i++) {
      if (currentTime < lyricData.value[i].time) {
        return i - 1
      }
    }
    return lyricData.value.length - 1
  }
</script>

<style lang="scss" scoped>
  .ltric {
    text-align: center;
    height: 600rpx;
    width: 100%;
    overflow: hidden;

    .ltric_container {
      transition: all 0.2s;
      width: 100%;
      text {
        width: 100%;
        display: block;
        line-height: 60rpx;
        transition: all 0.2s;
        min-height: 60rpx;
        overflow: hidden;
        color: rgba(255, 255, 255, 0.5);
      }

      .active {
        color: #fff;
        transform: scale(1.2);
      }
    }
  }
</style>